package org.e_gold.service.impl;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;
import org.e_gold.dao.ContractDAO;
import org.e_gold.dao.EventDAO;
import org.e_gold.dto.Cookies;
import org.e_gold.model.Contract;
import org.e_gold.model.Event;
import org.e_gold.service.ContractService;
import org.e_gold.util.Bet365;
import org.e_gold.util.CalcUtil;
import org.e_gold.util.StringUtil;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class ContractServiceImpl extends _NavigatorService implements ContractService, Bet365 {

    private static final Logger logger = Logger.getLogger(ContractServiceImpl.class);
    @Autowired
    private EventDAO eventDAO;

    @Autowired
    private ContractDAO contractDAO;

    @Override
    // production - backup
    public List<Contract> exposeAllContract(List<Event> events, Map<String, String> headers, Cookies cookies) {

        List<Contract> allContracts = new ArrayList<Contract>();
        if (events != null && events.size() > 0) {
            logger.info(":::::::::::::::::::::::::::");
            logger.info(":::::::::::::::::::::::::::");
            logger.info("::::::Start Contract:::::::");
            logger.info(":::::::::::::::::::::::::::");
            logger.info(":::::::::::::::::::::::::::");
            for (Event event : events) {
                logger.info("----------------------");
                logger.info("Begin expose contract - Event : " + event.getName());
                logger.info("----------------------");
                try {
                    Document contractPage = redirectNavigator(event.getLocation());
                    if (hasAllMarkets(contractPage)) {
                        // get all markets link and update event DB
                        Element eAllMarketsLink = contractPage.select(ALL_MARKETS_CLASS + " a").get(0);
                        event.setLocation("../coupon/" + eAllMarketsLink.attr("href"));
                        event.setLocationFull(BASE_SPORT + "coupon/" + eAllMarketsLink.attr("href"));
                        eventDAO.update(event);
                        contractPage = redirectNavigator(event.getLocation());
                    }
                    Elements eContract = contractPage.select("a[href^=/AddToBetslip.aspx]");
                    Set<Contract> setContracts = new HashSet<Contract>();
                    for (Element e : eContract) {
                        try {
                            // insert new or populate old contract
                            String contractStr = e.text();
                            String contractType = StringUtil.getContractType(contractStr);
                            Contract c = contractDAO.findByEventIdAndContractType(event.getId(), contractType);
                            if (c == null) {
                                c = new Contract();
                                contractDAO.insert(c);
                            }
                            c.setEvent(event);
                            c.setRate(CalcUtil.getRate(contractStr));
                            c.setContractType(contractType);
                            c.setBetSlipUrl(e.attr("href"));
                            setContracts.add(c);
                            contractDAO.update(c);
                            logger.info("Contract : " + event.getName() + " - " + event.getPlayTime() + " - " + c.getContractType() + " - " + c.getRate());
                            allContracts.add(c);
                        } catch (Exception e2) {
                            logger.info("expose contract error : " + e.text());
                        }
                    }
                    if (setContracts.size() > 0) {
                        event.setContracts(setContracts);
                    }
                    // Thread.sleep(CalcUtil.randomTime(1, 5) * 100);
                } catch (Exception e) {
                    logger.info("Expose event error : " + event.getName());
                }
                logger.info("----------------------");
                logger.info("End expose contract - Event : " + event.getName());
                logger.info("----------------------");
            }
            logger.info(":::::::::::::::::::::::::::");
            logger.info(":::::::::::::::::::::::::::");
            logger.info("::::::End Contract:::::::");
            logger.info(":: Total qualify contracts : " + allContracts.size() + "  ::");
            logger.info(":::::::::::::::::::::::::::");
        }
        return allContracts;
    }

    private boolean hasAllMarkets(Document contractPage) {

        try {
            return contractPage.select(ALL_MARKETS_CLASS).size() > 0;
        } catch (Exception e) {
            logger.error(e);
        }
        return false;
    }

    @Override
    public Contract getRunningContract() {

        return contractDAO.getRunningContract();
    }

    @Override
    public void updateFalseQualify() {

        contractDAO.updateFalseQualify();
    }

}
